package com.endbd.systemmanagement.controller.permission;


import com.endbd.feignapi.model.system.Job;
import com.endbd.feignapi.model.system.Module;
import com.endbd.feignapi.model.system.User;
import com.endbd.feignapi.util.LoginToken;
import com.endbd.feignapi.util.ResultMessage;
import com.endbd.systemmanagement.model.ResultBody;
import com.endbd.systemmanagement.service.permission.IPermissionService;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.*;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/system/permission")
public class PermissionControl {

    @Autowired
    private IPermissionService permissionService;

    @Autowired
    private RedisTemplate redisTemplate;

//    @RequestMapping("/login")
    public ResultBody login(String username, String password) {
//        if (true) {
//            Cookie cookie = new Cookie("JSESSIONID", session.getId());
//            cookie.setMaxAge(30*60);
//            cookie.setPath("/");
//            response.addCookie(cookie);
//            return new ResultBody(200, session.getId(), null);
//        }
        User user = permissionService.loginCheck(username, password);
        if (user == null) {
            ResultBody resultBody = new ResultBody();
            resultBody.setCode(401);
            resultBody.setMessage("账号或密码错误");
            return resultBody;
        }


        //redis检查是否已登录
        Map<String, User> loginUser = (Map<String, User>) redisTemplate.opsForValue().get("loginUser");
        if (loginUser == null) loginUser = new HashMap<>();
        if (loginUser.get(String.valueOf(user.getUId()))!=null) {
            Map<String, Date> loginTimeMap = (Map<String, Date>) redisTemplate.opsForValue().get("loginTime");
            if (loginTimeMap == null) loginTimeMap = new HashMap<>();
            Date loginTime = loginTimeMap.get(String.valueOf(user.getUId()));
            if (loginTime != null)  {
                long time = loginTime.getTime();
                if (new Date().getTime() - time < 1000 * 60 * 30) {
                    ResultBody resultBody = new ResultBody();
                    resultBody.setCode(402);
                    resultBody.setMessage("该账号已登录");
                    return resultBody;
                }
            }
        }


        //redis存User
        loginUser.put(String.valueOf(user.getUId()), user);
        redisTemplate.opsForValue().set("loginUser", loginUser);
        //redis存登录时间
        Map<String, Date> loginTime = (Map<String, Date>) redisTemplate.opsForValue().get("loginTime");
        if (loginTime == null) loginTime = new HashMap<>();
        loginTime.put(String.valueOf(user.getUId()), new Date());
        redisTemplate.opsForValue().set("loginTime", loginTime);
        //redis存Job
        Job job = permissionService.queryJobByUser(user);
        Map<String, Job> loginJob = (Map<String, Job>) redisTemplate.opsForValue().get("loginJob");
        if (loginJob == null) loginJob = new HashMap<>();
        loginJob.put(String.valueOf(user.getUId()), job);
        redisTemplate.opsForValue().set("loginJob", loginJob);
        //redis存Module
        List<List<Module>> module = permissionService.queryModuleByUser(user);
        Map<String, List<List<Module>>> loginModule = (Map<String, List<List<Module>>>) redisTemplate.opsForValue().get("loginModule");
        if (loginModule == null) loginModule = new HashMap<>();
        loginModule.put(String.valueOf(user.getUId()), module);
        redisTemplate.opsForValue().set("loginModule", loginModule);


        ResultBody resultBody = new ResultBody();
        resultBody.setCode(200);
        resultBody.setMessage("登录成功");
        resultBody.setData(user);
        return resultBody;
    }

    @RequestMapping("/login")
    public ResultBody login2(String username, String password) {
        User user = permissionService.loginCheck(username, password);
        if (user == null) {
            ResultBody resultBody = new ResultBody();
            resultBody.setCode(401);
            resultBody.setMessage("账号或密码错误");
            return resultBody;
        }

        //判断该账号是否已登录
        Map<String, LoginToken> loginToken = (Map<String, LoginToken>) redisTemplate.opsForValue().get("loginToken");
        if (loginToken == null) loginToken = new HashMap<>();
        LoginToken token = loginToken.get(String.valueOf(user.getUId()));
        if (token != null) {
            //该账号已登录无法登录
            if (new Date().getTime() - token.getLoginTime().getTime() < 1000 * 60 * 30) {
                ResultBody resultBody = new ResultBody();
                resultBody.setCode(402);
                resultBody.setMessage("该账号已登录");
                return resultBody;
            }
        }

        //未登录则读取用户信息
        LoginToken newToken = new LoginToken();
        newToken.setUser(user);
        newToken.setLoginTime(new Date());
        newToken.setToken(String.valueOf(UUID.randomUUID()));
        newToken.setJob(permissionService.queryJobByUser(user));
        newToken.setModules(permissionService.queryModuleByUser(user));

        //token存redis
        loginToken.put(String.valueOf(user.getUId()), newToken);
        redisTemplate.opsForValue().set("loginToken", loginToken);

        ResultBody resultBody = new ResultBody();
        resultBody.setCode(200);
        resultBody.setMessage("登录成功");
        resultBody.setData(newToken);
        return resultBody;
    }

    @RequestMapping("/getModule")
    public ResultBody getModule(@RequestHeader(required = false) String uId) {
//        Map<String, List<List<Module>>> loginModule = (Map<String, List<List<Module>>>) redisTemplate.opsForValue().get("loginModule");
//        if (loginModule == null) loginModule = new HashMap<>();
//        List<List<Module>> moduleLists = loginModule.get(uId);

        Map<String, LoginToken> loginToken = (Map<String, LoginToken>) redisTemplate.opsForValue().get("loginToken");
        if (loginToken == null) loginToken = new HashMap<>();
        List<List<Module>> moduleLists = loginToken.get(uId).getModules();
        if (moduleLists != null) {
            return new ResultBody(200, "获取模块", moduleLists);
        } else {
            return new ResultBody(401, "未登录", null);
        }
    }

    @RequestMapping("/logout/{uId}")
    public ResultBody logout(@PathVariable String uId) {
        try {
            Map<String, User> loginUser = (Map<String, User>) redisTemplate.opsForValue().get("loginUser");
            Map<String, Job> loginJob = (Map<String, Job>) redisTemplate.opsForValue().get("loginJob");
            Map<String, List<List<Module>>> loginModule = (Map<String, List<List<Module>>>) redisTemplate.opsForValue().get("loginModule");
            Map<String, Date> loginTime = (Map<String, Date>) redisTemplate.opsForValue().get("loginTime");

            loginUser.remove(uId);
            loginJob.remove(uId);
            loginModule.remove(uId);
            loginTime.remove(uId);

            redisTemplate.opsForValue().set("loginUser", loginUser);
            redisTemplate.opsForValue().set("loginJob", loginJob);
            redisTemplate.opsForValue().set("loginModule", loginModule);
            redisTemplate.opsForValue().set("loginTime", loginTime);
        } catch (Exception e) {
            return new ResultBody(500, "服务器异常", null);
        }

        return new ResultBody(200, "登出成功", null);
    }

    @RequestMapping("/logout")
    public ResultBody logout2(@RequestHeader(required = false) String uId,
                              @RequestHeader(value = "token", required = false) String strToken) {
        if (uId == null || strToken == null) {
            return new ResultBody(401, "未登录", null);
        }

        Map<String, LoginToken> loginToken = (Map<String, LoginToken>) redisTemplate.opsForValue().get("loginToken");
        if (loginToken == null) loginToken = new HashMap<>();
        LoginToken token = loginToken.get(uId);
        if (token != null && strToken.equals(token.getToken())) {
            loginToken.remove(uId);
        }

        redisTemplate.opsForValue().set("loginToken", loginToken);

        return new ResultBody(200, "登出成功", null);
    }

    @RequestMapping("/uIdCheck")
    public ResultBody uIdCheck(@RequestHeader(required = false) String uId,
                               @RequestHeader(value = "token", required = false) String strToken) {
        if (uId == null || strToken == null) {
            return new ResultBody(401, "未登录", null);
        }

        Map<String, LoginToken> loginToken = (Map<String, LoginToken>) redisTemplate.opsForValue().get("loginToken");
        if (loginToken == null) loginToken = new HashMap<>();

        LoginToken token = loginToken.get(uId);
        if (token == null || !strToken.equals(token.getToken())) {
            return new ResultBody(401, "未登录", null);
        }

        if (new Date().getTime() - token.getLoginTime().getTime() > 1000 * 60 * 30) {
            return new ResultBody(401, "未登录", null);
        }

        return new ResultBody(200, "已登录", null);
    }


}
